
package com.lxy.config.shiro;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;


/**
 * shiro 权限配置
 */

@Configuration
public class ShiroConfiguration {

    private static Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();


    @Bean(name="shiroRealm")
    public SecurityRealm shiroRealm() {
        SecurityRealm securityRealm = new SecurityRealm();
        securityRealm.setCredentialsMatcher(retryLimitSimpleCredentialsMatcher());
        securityRealm.setCachingEnabled(true);
        securityRealm.setAuthenticationCachingEnabled(false);
        securityRealm.setAuthenticationCacheName("authenticationCache");
        securityRealm.setAuthorizationCachingEnabled(false);
        securityRealm.setAuthorizationCacheName("authorizationCache");
        return securityRealm;
    }

    /*
     * 凭证匹配器
     * @return
     */

    @Bean
    public RetryLimitSimpleCredentialsMatcher retryLimitSimpleCredentialsMatcher() {
        RetryLimitSimpleCredentialsMatcher retryLimitSimpleCredentialsMatcher = new RetryLimitSimpleCredentialsMatcher(ehCacheManager());
        retryLimitSimpleCredentialsMatcher.setPasswordHelper(new PasswordHelper());
        return retryLimitSimpleCredentialsMatcher;
    }


/**
     * 缓存管理器 使用Ehcache实现
     * @return
     */

    @Bean
    public EhCacheManager ehCacheManager() {
        EhCacheManager em = new EhCacheManager();
        em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
        return em;
    }


/**
     * Shiro生命周期处理器
     * @return
     */

    @Bean
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }



/**
     * 安全管理器
     * @return
     */

    @Bean(name="securityManager")
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
        dwsm.setRealm(shiroRealm());
        dwsm.setRememberMeManager(rememberMeManager());
        dwsm.setCacheManager(ehCacheManager());
        dwsm.setSessionManager(sessionManager());
        return dwsm;
    }


/**
     * 自定义会话管理配置
     * @return
     */

    @Bean(name="sessionManager")
    public DefaultWebSessionManager sessionManager(){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        CacheSessionDAO sessionDAO =  new CacheSessionDAO();
        sessionDAO.setSessionIdGenerator(new JavaUuidSessionIdGenerator());
        sessionDAO.setActiveSessionsCacheName("shiro-activeSessionCache");
        sessionDAO.setCacheManager(ehCacheManager());
        sessionManager.setSessionDAO(sessionDAO);
        //毫秒
        sessionManager.setGlobalSessionTimeout(1800000);
        sessionManager.setDeleteInvalidSessions(true);
        //定时清理失效会话, 清理用户直接关闭浏览器造成的孤立会话
        sessionManager.setSessionValidationInterval(1800000);
        sessionManager.setSessionValidationSchedulerEnabled(true);


       /* QuartzSessionValidationScheduler scheduler = new QuartzSessionValidationScheduler();
        scheduler.setSessionValidationInterval(1800000);
        scheduler.setSessionManager(sessionManager());
        sessionManager.setSessionValidationScheduler(scheduler);*/



        //session 监听器
        Collection<SessionListener> listeners = new ArrayList<>();
        listeners.add(new MySessionListener());

        sessionManager.setSessionListeners(listeners);

        SimpleCookie cookie = new SimpleCookie();
        cookie.setName("sid");
        cookie.setMaxAge(180000);
        cookie.setHttpOnly(true);
        sessionManager.setSessionIdCookie(cookie);
        sessionManager.setSessionIdCookieEnabled(true);
        return sessionManager;
    }


/**
     * 记住帐户密码
     * @return
     */

    @Bean(name="rememberMeCookie")
    public SimpleCookie rememberMeCookie (){
        SimpleCookie cookie = new SimpleCookie("rememberMe");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(180000);
        return cookie;
    }

    @Bean(name="rememberMeManager")
    public CookieRememberMeManager rememberMeManager(){
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        return cookieRememberMeManager;
    }

    @Bean(name="shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        //登录地址
        shiroFilterFactoryBean.setLoginUrl("/login");
        //登录成功地址
        shiroFilterFactoryBean.setSuccessUrl("/home");
        //没有权限
        shiroFilterFactoryBean.setUnauthorizedUrl("/login");
        //地址过滤
        filterChainDefinitionMap.put("/loginValidate", "anon");
        filterChainDefinitionMap.put("/checkCode", "anon");
        filterChainDefinitionMap.put("/test", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/images/**", "anon");


        //需要验证
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean
                .setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }



}

